package com.rain.service.impl;

import cn.hutool.core.util.StrUtil;
import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.core.query.QueryWrapper;
import com.mybatisflex.spring.service.impl.ServiceImpl;
import com.rain.constant.UserConstant;
import com.rain.exception.BusinessException;
import com.rain.exception.ErrorCode;
import com.rain.exception.ThrowUtils;
import com.rain.mapper.ChatHistoryMapper;
import com.rain.dto.chathistory.ChatHistoryQueryRequest;
import com.rain.entity.App;
import com.rain.entity.ChatHistory;
import com.rain.entity.User;
import com.rain.enums.ChatHistoryMessageTypeEnum;
import com.rain.service.AppService;
import com.rain.service.ChatHistoryService;
import dev.langchain4j.data.message.AiMessage;
import dev.langchain4j.data.message.UserMessage;
import dev.langchain4j.memory.chat.MessageWindowChatMemory;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.time.LocalDateTime;
import java.util.List;

/**
 *  服务层实现。
 *
 * @author <a href="https://github.com/liyupi">程序员刘诗雨</a>
 */
@Slf4j
@Service
public class ChatHistoryServiceImpl extends ServiceImpl<ChatHistoryMapper, ChatHistory>  implements ChatHistoryService {

    @Resource
    private AppService appService;
    @Override
    public boolean addChatHistory(Long appId, Long userId, String message, String messageType) {
        // 基础校验
        ThrowUtils.throwIf(appId == null || appId <= 0, ErrorCode.PARAMS_ERROR, "应用ID不能为空");
        ThrowUtils.throwIf(StrUtil.isBlank(message), ErrorCode.PARAMS_ERROR, "消息内容不能为空");
        ThrowUtils.throwIf(StrUtil.isBlank(messageType), ErrorCode.PARAMS_ERROR, "消息类型不能为空");
        ThrowUtils.throwIf(userId == null || userId <= 0, ErrorCode.PARAMS_ERROR, "用户ID不能为空");

        ChatHistoryMessageTypeEnum messageTypeEnum = ChatHistoryMessageTypeEnum.getEnumByValue(messageType);
        if (messageTypeEnum == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "消息类型错误");
        }
        ChatHistory chatHistory = ChatHistory.builder().appId(appId)
                .userId(userId)
                .message(message)
                .messageType(messageTypeEnum.getValue()).build();
        return save(chatHistory);
    }

    @Override
    public boolean deleteByAppId(Long appId) {
        ThrowUtils.throwIf(appId == null || appId <= 0, ErrorCode.PARAMS_ERROR, "应用ID不能为空");
        QueryWrapper queryWrapper = QueryWrapper.create().eq("appId", appId);
        return remove(queryWrapper);
    }

    @Override
    public QueryWrapper getQueryWrapper(ChatHistoryQueryRequest chatHistoryQueryRequest) {
        QueryWrapper queryWrapper = new QueryWrapper();
        if(chatHistoryQueryRequest==null){
            return queryWrapper;
        }
        Long id = chatHistoryQueryRequest.getId();
        String message = chatHistoryQueryRequest.getMessage();
        String messageType = chatHistoryQueryRequest.getMessageType();
        Long appId = chatHistoryQueryRequest.getAppId();
        Long userId = chatHistoryQueryRequest.getUserId();
        LocalDateTime lastCreateTime = chatHistoryQueryRequest.getLastCreateTime();
        String sortField = chatHistoryQueryRequest.getSortField();
        String sortOrder = chatHistoryQueryRequest.getSortOrder();

        // 拼接查询条件
        queryWrapper.eq("id", id)
                .like("message", message)
                .eq("messageType", messageType)
                .eq("appId", appId)
                .eq("userId", userId);
        // 游标查询逻辑 - 只使用 createTime 作为游标
        if(lastCreateTime != null){
            queryWrapper.lt("createTime", lastCreateTime);
        }
        if(StrUtil.isNotBlank(sortField)){
            queryWrapper.orderBy(sortField,"ascend".equals(sortOrder));
        }else {
            queryWrapper.orderBy(sortField,false);
        }
        return queryWrapper;
    }


    @Override
    public Page<ChatHistory> listAppChatHistoryByPage(Long appId, User loginUser, LocalDateTime lastCreateTime, int pageSize) {
//        1,基础校验
        ThrowUtils.throwIf(appId == null || appId <= 0, ErrorCode.PARAMS_ERROR, "应用ID不能为空");
        ThrowUtils.throwIf(loginUser == null || loginUser.getId() == null || loginUser.getId() <= 0, ErrorCode.PARAMS_ERROR, "用户ID不能为空");
        App app = appService.getById(appId);
        ThrowUtils.throwIf(app == null, ErrorCode.PARAMS_ERROR, "应用不存在");
//        2,权限校验
        boolean isAdmin = UserConstant.ADMIN_ROLE.equals(loginUser.getUserRole());
        boolean isCreator = app.getUserId().equals(loginUser.getId());
        if(!isCreator || !isAdmin){
            throw new BusinessException(ErrorCode.NO_AUTH_ERROR, "无权限");
        }
//        3,构建查询条件
        ChatHistoryQueryRequest chatHistoryQueryRequest = new ChatHistoryQueryRequest();
        chatHistoryQueryRequest.setAppId(appId);
        chatHistoryQueryRequest.setLastCreateTime(lastCreateTime);
//        查询
        return this.page(new Page<>(1, pageSize), getQueryWrapper(chatHistoryQueryRequest));

    }

    /**
     * 加载对话历史到内存
     *
     * @param appId
     * @param chatMemory
     * @param maxCount 最多加载多少条
     * @return 加载成功的条数
     */
    @Override
    public int loadChatHistoryToMemory(long appId, MessageWindowChatMemory chatMemory, int maxCount) {
        try {
            QueryWrapper queryWrapper = QueryWrapper.create().eq(ChatHistory::getAppId, appId)
                    .orderBy(ChatHistory::getCreateTime, false)
                    .limit(1, maxCount);
            List<ChatHistory> historyList = this.list(queryWrapper);
            if(CollectionUtils.isEmpty(historyList)){
                return 0;
            }
            historyList = historyList.reversed();
            // 先清理历史缓存，防止重复加载
            chatMemory.clear();
            int loadedCount=0;
            for(ChatHistory history:historyList){
                if(ChatHistoryMessageTypeEnum.USER.getValue().equals(history.getMessageType())){
                    chatMemory.add(AiMessage.from(history.getMessage()));
                }else {
                    chatMemory.add(UserMessage.from(history.getMessage()));
                }
                loadedCount++;
            }
            log.info("成功为app{},加载了{}条消息",appId,loadedCount);
            return loadedCount;
        }catch (Exception e){
            log.error("为app{}加载消息失败，{}",appId,e.getMessage());
            return 0;
        }
    }

}